package com.spring.component.auth.utils;

import com.spring.component.utils.CollectionUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * @author liushihua
 * @since 2018年04月03日
 */
@Component
public class RequestIgnoreList {
  protected final Logger log = LoggerFactory.getLogger(this.getClass());

  @Autowired
  private WhiteResourceList whiteResourceList;
  private static List<String> IGNORE_URL_COMMON_LIST = new ArrayList<>();

  static {
    // 公共忽略url
    IGNORE_URL_COMMON_LIST.add(".*/login");
    IGNORE_URL_COMMON_LIST.add(".*/login[/?].*");
    IGNORE_URL_COMMON_LIST.add(".*swagger.*");
    IGNORE_URL_COMMON_LIST.add(".*/api-docs.*");
    IGNORE_URL_COMMON_LIST.add(".*/api/user/queryFunctionAuthority");
  }

  protected static boolean containsUrl(String url) {
    return IGNORE_URL_COMMON_LIST.stream().anyMatch(s -> url.matches(s));
  }

  public boolean match(ServletRequest servletRequest) {
    boolean match = false;
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    String requestURI = request.getRequestURI();
    match = containsUrl(requestURI);
    if (CollectionUtil.isNotBlank(whiteResourceList)) {
      match = match || whiteResourceList.getList().stream()
          .anyMatch(whiteResourceItem -> match(whiteResourceItem, request));
    }
    return match;
  }

  protected boolean match(WhiteResourceItem whiteResourceItem, ServletRequest servletRequest) {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    String frontType = request.getHeader("FrontType");
    String requestIP = request.getRemoteAddr();
    String requestURI = request.getRequestURI();
    if (this.log.isDebugEnabled()) {
      this.log.debug(
          String.format("Request front:%s, ip: %s, uri: %s", frontType, requestIP, requestURI));
    }
    return match(whiteResourceItem, frontType, requestIP, requestURI);
  }

  protected boolean match(WhiteResourceItem whiteResourceItem, String requestFrontType,
      String requestIP, String requestURI) {
    boolean match = false;
    String fromFront = whiteResourceItem.getFromfront();
    List<String> fromIPs = whiteResourceItem.getFromips();
    List<String> urls = whiteResourceItem.getUrls();
    if (this.log.isDebugEnabled()) {
      this.log.debug(String.format("white list - fromfront: %s, fromips: %s, uris: %s", fromFront,
          fromIPs, urls));
    }
    if (StringUtils.isNotBlank(fromFront) && fromFront.equalsIgnoreCase(requestFrontType)) {
      match = true;
    } else {
      match = false;
    }
    if (CollectionUtil.isNotBlank(fromIPs) && contains(fromIPs, requestIP)) {
      match = match;
    } else {
      match = false;
    }
    if (CollectionUtil.isNotBlank(urls) && contains(urls, requestURI)) {
      match = match;
    }
    return match;
  }

  public boolean contains(List<String> whiteIPs, String requestIP) {
    if (CollectionUtil.isBlank(whiteIPs)) {
      return false;
    }
    return whiteIPs.stream().anyMatch(s -> StringUtils.equals(s, requestIP));
  }

  public static void main(String[] args) {
    System.out.println(StringUtils.contains("1234", "123"));
  }
}
